package application;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.support.multidex.MultiDexApplication;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;

import com.example.menhoo.toollibrary.common.utils.SdCardUtil;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.bitmap.BitmapGlobalConfig;
import com.lidroid.xutils.cache.MD5FileNameGenerator;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.util.LogUtils;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import model.DownloadDbModel;
import service.DownLoadService;
import service.UDPPushService;

/**
 * Created by yanglei on 15/9/22.
 */
public abstract class UIApplication extends MultiDexApplication implements Thread.UncaughtExceptionHandler {

    public static final int Day=1000*60*60*24;
    public static final int Hours=1000*60*60;
    public static final int Minutes=1000*60;

    /**
     * 网络超时时间(通用)
     */
    public static int NetWorkTimeOut = 30 * 1000;
    /**
     * 程序的包名
     */
    public static String PackageName;
    /**
     * 后台是否运行和绑定下载服务
     */
    private static boolean isRunDownloadService = false;
    /**
     * 后台是否运行UDP推送服务
     */
    private static boolean isRunUDPPushService = false;
    /**
     * 是否监听网络状态事件(默认注册)
     */
    private static boolean isNetworkStateReceiver = true;
    /**
     * 程序的缓存目录名称 SD/app_name(程序的名称)/AppIconCacheDir(图标) 可能要单独管理
     */
    private static String AppIconCacheDir = "CacheIcon";
    /**
     * 程序的缓存目录名称 SD/app_name(程序的名称)/AppCacheDir
     */
    private static String AppCacheDir = "Cache";

    /**
     * 程序的缓存目录名称 SD/app_name(程序的名称)/AppDownLoadDir
     */
    private static String AppDownLoadDir = "文件下载";
    /**
     * 程序的缓存目录名称 SD/app_name(程序的名称)/AppDownLoadAppDir
     */
    private static String AppDownLoadAppDir = "app更新文件";
    /**
     * 是否是调试模式
     */
    private UIApplicationType UIAppType = UIApplicationType.Developer;
    /**
     * 数据库操作
     */
    private static DbUtils DB;
    private static String DB_Name="i8Office.db";

    /**
     * 设置key value 用于程序的快速设置页面
     */
    private static UIKeyValueSet mAppKeyValueSet;

    private static String Session;
    public static String getSession(){
        return Session;
    }
    public static void setSession(String session){
        LogUtils.d("Login session: " + session);
        Session=session;
    }
    private static Context context;
    @Override
    public void onCreate() {
        super.onCreate();
        PackageName = getPackageName();
        context = getApplicationContext();
        LogUtils.customTagPrefix = PackageName;
        initDB();
        mAppKeyValueSet = new UIKeyValueSet(this);
        //默认就用onlywifi的key用于下载
        mAppKeyValueSet.setInitKey(UIKeyValueSet.IsOnlyWiFiUploadAndDownload, false);
        //图片载入器线程数量
        BitmapGlobalConfig bitmapGlobalConfig = BitmapGlobalConfig.getInstance(this, getAppCachePath(this));
        bitmapGlobalConfig.setThreadPoolSize(5);
        bitmapGlobalConfig.setDefaultCacheExpiry(Day);//img缓存过期时间
        bitmapGlobalConfig.setDefaultConnectTimeout(NetWorkTimeOut);//请求连接超时时间
        bitmapGlobalConfig.setDiskCacheEnabled(true);
        bitmapGlobalConfig.setDiskCacheSize(200 * 1024 * 1024);//200mb
        bitmapGlobalConfig.setMemoryCacheEnabled(true);
        bitmapGlobalConfig.setMemCacheSizePercent(0.4f);//80%android内存

        //icon
        //图片载入器线程数量
        BitmapGlobalConfig iconGlobalConfig = BitmapGlobalConfig.getInstance(this, getAppIconCachePath(this));
        iconGlobalConfig.setThreadPoolSize(5);
        iconGlobalConfig.setDefaultCacheExpiry(Day*365);//img缓存过期时间
        iconGlobalConfig.setDefaultConnectTimeout(NetWorkTimeOut);//请求连接超时时间
        iconGlobalConfig.setDiskCacheEnabled(true);
        iconGlobalConfig.setDiskCacheSize(200 * 1024 * 1024);//200mb
        iconGlobalConfig.setMemoryCacheEnabled(true);
        iconGlobalConfig.setMemCacheSizePercent(0.4f);//80%android内存

        //初始化
        init();
        //停止所有任务
        DownLoadService downLoadService = new DownLoadService();
        downLoadService.stopAllDownloadTask(getDB());

        //是否开启UDP推送服务
        if(this.isRunUDPPushService){
            Intent udp_service = new Intent(this, UDPPushService.class);
            this.startService(udp_service);
        }

        //配置多选图片，选择器
        if(!ImageLoader.getInstance().isInited()){
            ImageLoaderConfiguration config = null;
            config = new ImageLoaderConfiguration.Builder(this)
                    .threadPriority(Thread.NORM_PRIORITY - 2)
                    .diskCacheSize(500 * 1024 * 1024)
                    .diskCacheFileNameGenerator(new Md5FileNameGenerator())
                    .tasksProcessingOrder(QueueProcessingType.LIFO).build();
            ImageLoader.getInstance().init(config);
        }

        //环境
        if (UIAppType.equals(UIApplicationType.Developer)) {
            debug();
        } else {
            prduct();
            //设置Thread Exception Handler
            Thread.setDefaultUncaughtExceptionHandler(this);
        }
    }
    public static Context getContext() {
        return context;
    }
    /**
     * 得到 是否监听网络状态事件
     *
     * @return
     */
    public static boolean isNetworkStateReceiver() {
        return isNetworkStateReceiver;
    }

    /**
     * 设置 是否监听网络状态事件
     *
     * @param isNetworkStateReceiver
     */
    public void setIsNetworkStateReceiver(boolean isNetworkStateReceiver) {
        UIApplication.isNetworkStateReceiver = isNetworkStateReceiver;
    }

    /**
     * 设置是否运行UDP推送服务
     *
     * @param isRun true绑定  false不绑定  默认为不绑定
     */
    public void setRunUDPPushService(boolean isRun) {
        isRunUDPPushService = isRun;
    }

    /**
     * 得到是否运行UDP推送服务
     *
     * @return
     */
    public static boolean getRunUDPPushService() {
        return isRunUDPPushService;
    }

    /**
     * 设置是否运行和绑定"下载/上传服务"
     *
     * @param isRun true绑定  false不绑定  默认为不绑定
     */
    public void setRunDownloadService(boolean isRun) {
        isRunDownloadService = isRun;
    }

    /**
     * 得到是否运行和绑定"下载/上传服务"
     *
     * @return
     */
    public static boolean getRunDownloadService() {
        return isRunDownloadService;
    }

    private void initDB(){
        int version = 1;
        try {
            PackageInfo pi=this.getPackageManager().getPackageInfo(this.getPackageName(), 0);
            version = pi.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        this.DB = DbUtils.create(this, DB_Name, version, new DbUtils.DbUpgradeListener() {
            @Override
            public void onUpgrade(DbUtils db, int oldVersion, int newVersion) {
                DBUpdate(db,oldVersion,newVersion);
            }
        });
    }

    /**
     * 重写此方法进行数据库版本更新
     * @param oldVersion
     * @param newVersion
     */
    public void DBUpdate(DbUtils db, int oldVersion, int newVersion){

    }
    /**
     * 得到数据库操作对象
     *
     * @return
     */
    public static DbUtils getDB() {
        return DB;
    }

    /**
     * 设置app的开发类型环境,是'生产'还是'调试'环境
     *
     * @param type app环境类型
     */
    public void setUIApplicationType(UIApplicationType type) {
        this.UIAppType = type;
    }

    /**
     * 初始化
     */
    public abstract void init();

    /**
     * 调试环境
     */
    public abstract void debug();

    /**
     * 生产环境
     */
    public abstract void prduct();

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        LogUtils.e("警告!警告! 应用程序强制退出:" + ex.getMessage());
    }

    /**
     * 得到app的缓存路径
     *
     * @return
     */
    public static String getAppCachePath(Context context) {
        return SdCardUtil.getCurrAppSaveDir(context,
                AppCacheDir, true);
    }

    /**
     * 得到app icon图标的缓存路径
     *
     * @return
     */
    public static String getAppIconCachePath(Context context) {
        return SdCardUtil.getCurrAppSaveDir(context,
                AppIconCacheDir, true);
    }

    /**
     * 得到app的下载路径
     *
     * @return
     */
    public static String getAppDownLoadPath(Context context) {
        return getAppDownLoadPath(context, false);
    }

    /**
     * 得到app的下载路径 name 会被md5编码 完整的格式是 app的下载路径/name的md5编码.temp
     *
     * @param context
     * @param name
     * @return
     */
    public static String getAppDownLoadPath(Context context, String name) {

        String md5 = new MD5FileNameGenerator().generate(name);

        return getAppDownLoadPath(context, false) + "/" + md5 + ".temp";
    }

    /**
     * 得到app的下载路径
     *
     * @param context
     * @param createAutoTimeFile 是否创建一个 以当前时间的getTime()创建一个.temp文件
     * @return
     */
    public static String getAppDownLoadPath(Context context, boolean createAutoTimeFile) {

        if (createAutoTimeFile) {
            return SdCardUtil.getCurrAppSaveDir(context,
                    AppDownLoadDir, true) + "/" + new Date().getTime() + ".temp";
        } else {
            return SdCardUtil.getCurrAppSaveDir(context,
                    AppDownLoadDir, true);
        }

    }

    /**
     * 得到app更新文件的的下载路径
     */
    public static String getAppDownLoadAppPath(Context context, String name) {

        String md5 = new MD5FileNameGenerator().generate(name);

        return SdCardUtil.getApkPath() + "/" + md5 + ".temp";
}

    /**
     * 得到app更新文件的的下载路径
     */
    public static String getAppDownLoadAppPath(Context context, boolean createAutoTimeFile) {

        if (createAutoTimeFile) {
            return SdCardUtil.getCurrAppSaveDir(context,
                    AppDownLoadAppDir, true) + "/" + new Date().getTime() + ".temp";
        } else {
            return SdCardUtil.getCurrAppSaveDir(context,
                    AppDownLoadAppDir, true);
        }

    }

    /**
     * 得到一个动画对象 (渐入效果)
     *
     * @return
     */
    public static AnimationSet getAnimationSet() {
        return getAnimationSet(500);
    }

    /**
     * 得到一个动画对象 (渐入效果)
     *
     * @return
     */
    public static AnimationSet getAnimationSet(long duration) {
        //创建一个AnimationSet对象，参数为Boolean型，
        //true表示使用Animation的interpolator，false则是使用自己的
        AnimationSet animationSet = new AnimationSet(true);
        //创建一个AlphaAnimation对象，参数从完全的透明度，到完全的不透明
        AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
        //设置动画执行的时间
        alphaAnimation.setDuration(duration);
        //将alphaAnimation对象添加到AnimationSet当中
        animationSet.addAnimation(alphaAnimation);
        return animationSet;
    }

    /**
     * 得到一个动画对象
     *
     * @return
     */
    public static Animation getAnimationFromResId(Context context,int resId) {

        Animation operatingAnim = AnimationUtils.loadAnimation(context, resId);
        LinearInterpolator lin = new LinearInterpolator();
        operatingAnim.setInterpolator(lin);
//        setInterpolator表示设置旋转速率。LinearInterpolator为匀速效果，Accelerateinterpolator为加速效果、DecelerateInterpolator为减速效果，具体可见android:interpolator的介绍。


        return operatingAnim;
    }

    /**
     * 是否下载过这个url的文件
     *
     * @param url
     * @return
     */
    public static boolean existsDownloadFile(String url) {
        DownloadDbModel downloadDbModel = getDownloadFile(url);
        if (downloadDbModel != null) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据url返回一个已经下载过的文件
     *
     * @param url
     * @return
     */
    public static DownloadDbModel getDownloadFile(String url) {
        try {

            List<DownloadDbModel> list = getDownloadFiles();
            if (list != null)
                for (DownloadDbModel item : list) {
                    if (item.url.equalsIgnoreCase(url)) {
                        return item;
                    }
                }

        } catch (Exception e) {
            LogUtils.e(e.getMessage() + "");
        }

        return null;
    }

    /**
     * 根据tag返回一个已经下载过的文件
     *
     * @param Tag
     * @return
     */
    public static DownloadDbModel getDownloadFileForTag(String Tag) {
        try {
//
//            List<DownloadDbModel> list = getDownloadFiles();
//          //  LogUtils.e("getDownloadFileForTag=="+list.size());
//            LogUtils.e("getDownloadFileForTag---Tag=="+Tag);
//            if (list != null)
//                for (DownloadDbModel item : list) {
//                    LogUtils.e("getDownloadFileForTag-list--Tag=="+item.tag);
//                    if (item.tag.equalsIgnoreCase(Tag)) {
//                        return item;
//                    }
//                }
            DownloadDbModel downloadDbModel = getDB().findFirst(Selector.from(DownloadDbModel.class).where
                    ("tag", "==", Tag));
            return downloadDbModel;

        } catch (Exception e) {
            LogUtils.e(e.getMessage() + "");
        }

        return null;
    }

    /**
     * 返回下载过的文件(会移除不存在的文件)
     *
     * @return
     */
    public static List<DownloadDbModel> getDownloadFiles() {
        try {
            List<DownloadDbModel> removeList = new ArrayList();
            List<DownloadDbModel> tempList = new ArrayList();
            List<DownloadDbModel> list = getDB().findAll(Selector.from(DownloadDbModel.class).orderBy("updateTime", true));

            if (list != null && list.size() > 0) {
                //删除无用的数据
                for (DownloadDbModel item : list) {
                    File file = new File(item.path);
                    if (!file.exists() && item.isComplete) {
                        //如果不存在
                        LogUtils.e("移除数据:" + item.name);
                        removeList.add(item);
                    } else {
                        //看看是不是.temp临时文件
                        if (file.getName().indexOf(".temp") >= 0) {
                            tempList.add(item);
                        }
                    }
                }

                if (removeList.size() > 0) {
                    getDB().deleteAll(removeList);
                    list.removeAll(removeList);
                }
                if (tempList.size() > 0) {
                    list.removeAll(tempList);
                }

                return list.size() > 0 ? list : null;
            } else {
                return null;
            }


        } catch (Exception e) {
            LogUtils.e(e.getMessage() + "");
            return null;
        }

    }

//    @Override
//    protected void attachBaseContext(Context base) {
//        super.attachBaseContext(base);
//        MultiDex.install(this);
//    }

    public static UIKeyValueSet getAppKeyValueSet() {
        return mAppKeyValueSet;
    }

}
